<template>
  <wd-tabbar
    fixed
    v-model="tabBarStore.state.index"
    bordered
    safeAreaInsetBottom
    placeholder
    :zIndex="zIndex"
    @change="selectTabBar"
  >
    <template v-for="(item, idx) in getTabBarList" :key="item.id || `${idx}`">
      <template v-if="hasAuth(item.authority) && item.visible !== false">
        <slot :name="item.id || `${idx}`" v-bind="{ item, index: idx }">
          <template v-if="!item.button">
            <wd-tabbar-item :title="getText(item)" :name="item.id || idx" style="cursor: pointer">
              <template #icon>
                <wd-icon
                  v-if="item.iconType === 'wot'"
                  :name="getIcon(item.id || idx, item)"
                  size="25px"
                  :class="[
                    (item.id || idx) === tabBarStore.getIndex ? 'is-active' : 'is-inactive',
                    (item.id || idx) === tabBarStore.getIndex
                      ? 'animate__animated animate__pulse'
                      : '',
                  ]"
                />
                <view
                  v-else-if="item.iconType === 'unocss' || item.iconType === 'iconfont'"
                  h-25px
                  w-25px
                  :class="[
                    getIcon(item.id || idx, item),
                    (item.id || idx) === tabBarStore.getIndex ? 'is-active' : 'is-inactive',
                    (item.id || idx) === tabBarStore.getIndex
                      ? 'animate__animated animate__pulse'
                      : '',
                  ]"
                />
                <image
                  v-else-if="item.iconType === 'local'"
                  :src="getIcon(item.id || idx, item)"
                  h-25px
                  w-25px
                  :class="[
                    (item.id || idx) === tabBarStore.getIndex
                      ? 'animate__animated animate__pulse'
                      : '',
                  ]"
                />
              </template>
            </wd-tabbar-item>
          </template>
          <template v-else>
            <view
              class="wd-tabbar-item"
              style="cursor: pointer"
              @click="selectTabBar({ value: idx })"
            >
              <view class="wd-tabbar-item__body">
                <view class="tabbar-button">
                  <wd-icon
                    v-if="item.iconType === 'wot'"
                    :name="getIcon(item.id || idx, item)"
                    :size="item.iconSize || (item?.text ? '25px' : '40px')"
                  />
                  <view
                    v-else-if="item.iconType === 'unocss' || item.iconType === 'iconfont'"
                    :size="item.iconSize || (item?.text ? '25px' : '40px')"
                    :class="[getIcon(item.id || idx, item)]"
                    :style="`font-size: ${item.iconSize || (item?.text ? '25px' : '40px')}`"
                  />
                  <image
                    v-else-if="item.iconType === 'local'"
                    :src="getIcon(item.id || idx, item)"
                    :size="item.iconSize || (item?.text ? '25px' : '40px')"
                    :mode="item.iconMode || 'scaleToFill'"
                  />
                </view>
                <text
                  v-if="item?.text"
                  class="wd-tabbar-item__body-title is-inactive text tabbar-button-text"
                >
                  {{ item.text }}
                </text>
              </view>
            </view>
          </template>
        </slot>
      </template>
    </template>
    <view v-if="getShowMore" class="wd-tabbar-item" style="cursor: pointer" @click="showMoreClick">
      <view class="wd-tabbar-item__body">
        <view class="tabbar-button">
          <ea-folder :list="getFolderList" size="25px" scale="0px" :show-count="4" />
        </view>
        <text class="wd-tabbar-item__body-title is-inactive text tabbar-button-text">
          {{ t('component.tabbar.more') }}
        </text>
      </view>
    </view>
  </wd-tabbar>
  <ea-floating-panel
    v-model="showMore"
    :safe-area-inset-bottom="true"
    :content-draggable="true"
    :anchors="['30%', '60%', '100%']"
    :slide-closable="true"
  >
    <wd-row :gutter="20">
      <template v-for="(item, idx) in getFolderList" :key="item.id || `${idx}`">
        <template v-if="hasAuth(item.authority)">
          <wd-col :span="6">
            <view class="wd-tabbar-item__body">
              <ea-gesture class="tabbar-button">
                <wd-icon
                  v-if="item.avatarType === 'wot'"
                  :name="item.avatar"
                  :size="item.avatarSize || (item?.avatarText ? '50px' : '70px')"
                />
                <view
                  v-else-if="item.avatarType === 'unocss' || item.avatarType === 'iconfont'"
                  :size="item.avatarSize || (item?.avatarText ? '50px' : '70px')"
                  :class="[item.avatar]"
                  :style="`font-size: ${item.avatarSize || (item?.avatarText ? '50px' : '70px')}`"
                />
                <image
                  v-else-if="item.avatarType === 'local'"
                  :src="item.avatar"
                  :size="item.avatarSize || (item?.avatarText ? '50px' : '70px')"
                  :mode="item.avatarMode || 'scaleToFill'"
                />
              </ea-gesture>
              <text v-if="item?.avatarText" class="tabbar-button-avatar-text">
                {{ item.avatarText }}
              </text>
            </view>
          </wd-col>
        </template>
      </template>
    </wd-row>
  </ea-floating-panel>
</template>

<script setup lang="ts">
  // unocss icon 动态渲染不生效，需要在这里写一遍才能生效！注释掉也是生效的，但是必须要有！PS：已在 uno.config.ts 中配置解决。
  // i-line-md:home
  import { EaFloatingPanel } from '@/components/ea-floating-panel';
  import { EaFolder, FolderDataType } from '@/components/ea-folder';
  import { EaGesture } from '@/components/ea-gesture';
  import { useAuth } from '@/hooks/useAuth';
  import { useI18n } from '@/locale';
  import { t as $t } from '@/locale/utils';
  import { getIsTabbar } from '@/utils';
  import { isFunction, isString } from '@/utils/is';

  import { TabBarType, useTabBarStore } from '../';
  import { tabBarProps } from './props';

  defineOptions({
    name: 'ea-tabbar',
    options: {
      virtualHost: true,
      addGlobalClass: true,
      styleIsolation: 'shared',
    },
  });
  const props = defineProps(tabBarProps);
  const emit = defineEmits(['switch', 'click']);

  const { t } = useI18n();
  const { hasAuth } = useAuth();
  const tabBarStore = useTabBarStore(props.id);

  /** 获取列表 */
  const getTabBarList = computed<
    (TabBarType & {
      /** 序号 */
      order: number;
    })[]
  >(
    () =>
      tabBarStore.getList ||
      props.list?.map((m) => {
        return { ...m, order: 0 };
      }) ||
      [],
  );
  /** 获取隐藏的列表 */
  const getHideTabBarList = computed(() => getTabBarList.value.filter((o) => o.visible === false));
  /** 获取是否显示更多 */
  const getShowMore = computed(() => props.showMore && getHideTabBarList.value?.length > 0);
  /** 获取文件夹列表 */
  const getFolderList = computed<FolderDataType[]>(() => {
    const list = getHideTabBarList.value?.map((m) => {
      return {
        ...m, // 额外的属性
        order: m.order, // 序号
        id: m.id, // 编号
        authority: m.authority, // 授权标识
        avatarType: m.avatarType || m.iconType, // 头像类型
        avatarSize: m.avatarSize, // 头像大小
        avatarMode: m.avatarMode || m.iconMode, // 头像裁剪、缩放的模式，仅 local 类型有效。
        avatar: m.avatar || m.selectedIcon || m.icon, // 头像
        avatarText: translate(m.avatarText || m.text), // 头像文字
        visible: true,
      };
    });
    return list || [];
  });
  /** 显示更多浮动面板 */
  const showMore = ref(false);

  /** 翻译文字 */
  function translate(text: string) {
    text = text || '';
    // 多语言翻译处理，参照原生机制。
    if (text.startsWith('%') && text.endsWith('%')) {
      text = $t(text.slice(1, -1));
    }
    return text;
  }
  /** 获取图标 */
  function getIcon(idx: string | number, item: TabBarType) {
    const selectedIcon =
      isString(item?.selectedIcon) && item?.selectedIcon ? item?.selectedIcon : item?.icon;
    return idx === tabBarStore.getIndex ? selectedIcon : item?.icon;
  }
  /** 获取按钮文字 */
  function getText(item: TabBarType) {
    return translate(item?.text);
  }
  /** 获取页面路径 */
  function getPath(item: TabBarType) {
    let pagePath = item?.pagePath || '';
    if (!pagePath.startsWith('/')) {
      pagePath = `/${item.pagePath}`;
    }
    return pagePath;
  }

  /** 选择标签栏 */
  async function selectTabBar({ value: index }: { value: number }) {
    showMore.value = false;
    const tabBarList = getTabBarList.value;
    const tabBar = { ...tabBarList[index], index };
    const { switchTab, switchFn, clickFn } = props;
    if (!tabBar.button) {
      let flag = true;
      if (switchFn && isFunction(switchFn)) {
        flag = await switchFn(tabBar);
      }
      if (flag) {
        tabBarStore.setIndex(index);
        emit('switch', tabBar);
        // 设置导航栏标题
        uni.setNavigationBarTitle({
          title: getText(tabBar),
        });
        if (switchTab) {
          const url = getPath(tabBar);
          uni.switchTab({ url });
        }
      }
    } else {
      if (clickFn && isFunction(clickFn)) {
        await clickFn(tabBar);
      }
      emit('click', tabBar);
    }
  }
  /** 更多按钮点击 */
  function showMoreClick() {
    showMore.value = !showMore.value;
  }

  onLoad(() => {
    // 解决原生 tabBar 未隐藏导致有2个 tabBar 的问题
    if (getIsTabbar()) {
      uni.hideTabBar({
        fail(err) {
          console.error('hideTabBar', err);
        },
        // success(res) {
        //   console.log('hideTabBar success: ', res);
        // },
      });
    }
    // 设置导航栏标题
    const index = tabBarStore.getIndex;
    const tabBarList = getTabBarList.value;
    const tabBar = { ...tabBarList[index], index };
    uni.setNavigationBarTitle({
      title: getText(tabBar),
    });

    // 处理当前页面首次加载标识
    const currentPage = getCurrentPages().pop();

    if (props.switchTab) {
      // 根据指定的存储标签进行跳转，修复载入时活跃页面与 tabBar 高亮不对应的问题。
      const tabBar = tabBarList[tabBarStore.getIndex];
      if (tabBar) {
        if (currentPage?.route !== tabBar.pagePath) {
          const url = getPath(tabBar);
          if (url) {
            uni.switchTab({ url });
          }
        }
      }
    }
  });
</script>

<style lang="scss" scoped>
  @import 'wot-design-uni/components/wd-tabbar-item/index';

  .wd-tabbar-item__body {
    display: flex;
    align-items: center;
    justify-items: center;
  }

  @keyframes pulse {
    0% {
      transform: scale(1);
    }
    50% {
      transform: scale(1.3);
    }
    100% {
      transform: scale(1);
    }
  }

  @keyframes clickEffect {
    0% {
      transform: scale(1);
    }
    50% {
      transform: scale(0.85);
    }
    100% {
      transform: scale(1);
    }
  }

  .animate__pulse {
    animation: pulse 0.3s;
    animation-timing-function: ease-in-out;
  }

  ::v-deep .tabbar-button {
    display: flex;
    align-items: center;
    justify-items: center;
  }
  ::v-deep .tabbar-button:active {
    // animation: clickEffect 0.1s ease;
    opacity: 0.6;
  }

  ::v-deep .tabbar-button:active + .tabbar-button-text {
    color: var(--wot-tabbar-active-color, var(--wot-color-theme, #4d80f0));
  }

  .tabbar-button-avatar-text {
    width: 100%;
    margin-top: 5rpx;
    font-size: 22rpx;
    text-align: center;
  }
</style>
